﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Reflection;

namespace Clipping.Utils
{
    /// <summary>
    /// 界面View操作的辅助类
    /// </summary>
    public static class ViewHelper
    {
        public static IEnumerable<T> EnumWPFChildObject<T>(DependencyObject parent, bool deep = false, bool loadLazyControl = true) where T : class
        {
            if (parent == null)
                yield break;

           

            //特殊处理Content
            object content = null;
            if (parent is System.Windows.Controls.ContentControl && (parent as System.Windows.Controls.ContentControl).Content != null)
            {
                content = (parent as System.Windows.Controls.ContentControl).Content;

                if (content is T)
                    yield return content as T;

                //递归调用
                if (!(content is T) || deep)
                {
                    if (content is DependencyObject)
                        foreach (T o in EnumWPFChildObject<T>(content as DependencyObject, deep, loadLazyControl))
                            yield return o;

                    yield break;
                }
            }

            if (!(parent is Visual))
            {
                yield break;
            }
            else
            {
                //遍历所有子对象
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); ++i)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(parent, i);

                    if (child == null || child == content)
                        continue;

                    if (child is T)
                    {
                        yield return child as T;

                        if (!deep)
                            continue;
                    }

                    //TabControl的ChildrenCount可能为零，需要特殊处理
                    if (child is System.Windows.Controls.TabControl)
                    {
                        System.Windows.Controls.TabControl tc = child as System.Windows.Controls.TabControl;
                        for (int j = 0; j < tc.Items.Count; ++j)
                        {
                            DependencyObject tabItem = tc.ItemContainerGenerator.ContainerFromItem(tc.Items[j]);
                            if (tabItem == null)
                                tabItem = tc.Items[j] as System.Windows.Controls.TabItem;

                            if (tabItem != null)
                            {
                                foreach (T o in EnumWPFChildObject<T>(tabItem as DependencyObject, deep, loadLazyControl))
                                    yield return o;
                            }
                        }
                    }

                    //如果没有子元素了就不递归处理了
                    if (VisualTreeHelper.GetChildrenCount(child) <= 0)
                        continue;

                    //递归调用
                    foreach (T o in EnumWPFChildObject<T>(child, deep, loadLazyControl))
                        yield return o;
                }
            }
        }

        public static T TryFindParentWPF<T>(DependencyObject child) where T : class
        {
            //get parent item     
            DependencyObject parentObject = GetParentObject(child);

            if (parentObject == null && child is System.Windows.Controls.Grid)
                parentObject = (child as System.Windows.Controls.Grid).Parent;

            //we've reached the end of the tree    
            if (parentObject == null)
            {
                return null;     //check if the parent matches the type we're looking for    
            }

            T parent = parentObject as T;

            if (parent != null)
            {
                return parent;
            }
            else
            {
                //use recursion to proceed with next level       
                return TryFindParentWPF<T>(parentObject);
            }
        }
        
        public static DependencyObject GetParentObject(DependencyObject child)
        {
            if (child == null)
                return null;

            ContentElement contentElement = child as ContentElement;

            DependencyObject parent = null;

            if (contentElement != null)
            {
                parent = ContentOperations.GetParent(contentElement);

                if (parent != null)
                    return parent;

                FrameworkContentElement fce = contentElement as FrameworkContentElement;

                return fce != null ? fce.Parent : null;
            }

            //if it's not a ContentElement, rely on VisualTreeHelper     
            parent = VisualTreeHelper.GetParent(child);

            if (parent == null && child is FrameworkElement)
                return (child as FrameworkElement).Parent;

            return parent;
        }

    }
}
